package com.example.twoscroolview.view

import android.graphics.*
import android.graphics.drawable.Drawable
import android.graphics.PointF
import android.view.animation.LinearInterpolator
import android.animation.ValueAnimator as ValueAnimator


/**
 * 绘制鱼+鱼的动画
 */
class FishDrawable : Drawable() {
    //yutou zuobiao
    lateinit var headPoint: PointF
    var mPaint: Paint? = null
    var mPath: Path? = null
    val OTHER_ALPHA = 110
    //鱼开始游戏加速度
    var frequence= 1f
    /**
     * 鱼的重心（中心 鱼游动转圈会根据这个值）
     */
     var mMiddlePoint: PointF? = null

    //鱼头摇晃的主要角度 0 为右 90 为上
    var mFishMainAngle=90f
    //鱼头的大小 高度
     val HEAD_RADIUS = 40f
    //身体的成都
      val BODY_LENGTH = HEAD_RADIUS* 3.2F
    //寻找鱼鳍起点坐标
    //鱼鳍的长度
      val FIND_FINS_LENTH = 0.9F* HEAD_RADIUS
      val FINS_LENTH =1.3F * HEAD_RADIUS

    //鱼尾
   // 鱼尾巴上圆下圆组成一个梯形 半径
    private  val BIG_CIRCLE_RADIUS:Float= (0.7*HEAD_RADIUS).toFloat()
    private  val MIDDLE_CIRCLE_RADIUS:Float= (0.6*BIG_CIRCLE_RADIUS).toFloat()
    private  val SMALL_CIRCLE_RADIUS:Float= (0.4*MIDDLE_CIRCLE_RADIUS).toFloat()
//线长
    private  val FIND_MIDDLE_CIRCLE_LENGTH: Float = ((0.6+1f)*BIG_CIRCLE_RADIUS).toFloat()
    private  val FIND_SMALL_CIRCLE_LENGTH: Float = ((0.4+2.7)*MIDDLE_CIRCLE_RADIUS).toFloat()
    //三角形的线长
    private  val FIND_TRIANGLE:Float= (MIDDLE_CIRCLE_RADIUS *2.7).toFloat()
    private var animatorValue = 0f
    init {
        mPaint = Paint()
        mPath = Path()
        mPaint?.isAntiAlias = true
        mPaint?.isDither = true
        mPaint?.style = Paint.Style.FILL
        mPaint?.setARGB(OTHER_ALPHA, 244, 92, 71)
        mMiddlePoint = PointF(4.19f * HEAD_RADIUS, 4.19f * HEAD_RADIUS)
        val valueAnimator =ValueAnimator.ofFloat(0f,720f)
        valueAnimator.duration = 15*1000
        valueAnimator.repeatMode = ValueAnimator.RESTART
        valueAnimator.repeatCount =ValueAnimator.INFINITE
        valueAnimator.interpolator = LinearInterpolator()
        valueAnimator.addUpdateListener {
            animatorValue = it.animatedValue as Float
            invalidateSelf()
        }

        valueAnimator.start()
    }

    override fun draw(canvas: Canvas) {
        //鱼头朝向 默认0
        val fishAngle :Float= (mFishMainAngle+Math.sin(Math.toRadians(animatorValue.toDouble()*1.2))*10).toFloat()
        //鱼头圆心的点
         headPoint = calculatePoint(mMiddlePoint!!,BODY_LENGTH/2,fishAngle)
        canvas.drawCircle(headPoint.x,headPoint.y,HEAD_RADIUS,mPaint!!)
        //右鱼鳍
        val rightFinsPoint =calculatePoint(headPoint,FIND_FINS_LENTH,fishAngle-110)
        //zuo鱼鳍
        val leftFinsPoint =calculatePoint(headPoint,FIND_FINS_LENTH,fishAngle+110)
        makeFins(canvas,rightFinsPoint,fishAngle,true)
        makeFins(canvas,leftFinsPoint,fishAngle,false)
        val bodyBottomCenterPoint = calculatePoint(headPoint,BODY_LENGTH,fishAngle-180)
            //画节支
     val PointF= makeSegment(canvas,bodyBottomCenterPoint,BIG_CIRCLE_RADIUS,MIDDLE_CIRCLE_RADIUS,
            FIND_MIDDLE_CIRCLE_LENGTH,fishAngle,true)
        //画节支2
        makeSegment(canvas,PointF,MIDDLE_CIRCLE_RADIUS,SMALL_CIRCLE_RADIUS,
            FIND_SMALL_CIRCLE_LENGTH,fishAngle,false)
        //hua尾巴
//        val triangleLength = Math.abs((Math.sin(Math.toRadians(animatorValue.toDouble()))*1.5).toFloat()*BIG_CIRCLE_RADIUS)
//        maketriangel(canvas, PointF!!,fishAngle,triangleLength,BIG_CIRCLE_RADIUS)
//        maketriangel(canvas, PointF!!,fishAngle,triangleLength-20,BIG_CIRCLE_RADIUS-20)

        maketriangel(canvas, PointF!!,fishAngle,FIND_TRIANGLE,BIG_CIRCLE_RADIUS)
        maketriangel(canvas, PointF!!,fishAngle,FIND_TRIANGLE-10,BIG_CIRCLE_RADIUS-20)

        makeBody(canvas, headPoint!!,bodyBottomCenterPoint,fishAngle)

    }
    private fun makeBody(
        canvas: Canvas,
        headPoint: PointF,
        bigCircleCenterPoint: PointF,
        fishAngle: Float
    ) {
        // 先求头部圆和大圆直径上的四个点
        val upperLeftPoint = calculatePoint(headPoint, HEAD_RADIUS, fishAngle + 90)
        val upperRightPoint = calculatePoint(headPoint, HEAD_RADIUS, fishAngle - 90)
        val bottomLeftPoint =
            calculatePoint(bigCircleCenterPoint, BIG_CIRCLE_RADIUS, fishAngle + 90)
        val bottomRightPoint =
            calculatePoint(bigCircleCenterPoint, BIG_CIRCLE_RADIUS, fishAngle - 90)

        // 两侧的控制点，长度和角度是在画图调整后测量出来的
        val controlLeft = calculatePoint(
            headPoint, BODY_LENGTH * 0.56f,
            fishAngle + 130
        )
        val controlRight = calculatePoint(
            headPoint, BODY_LENGTH * 0.56f,
            fishAngle - 130
        )

        // 绘制
        mPath!!.reset()
        mPath!!.moveTo(upperLeftPoint.x, upperLeftPoint.y)
        mPath!!.quadTo(controlLeft.x, controlLeft.y, bottomLeftPoint.x, bottomLeftPoint.y)
        mPath!!.lineTo(bottomRightPoint.x, bottomRightPoint.y)
        mPath!!.quadTo(controlRight.x, controlRight.y, upperRightPoint.x, upperRightPoint.y)
        mPaint!!.alpha = OTHER_ALPHA
        canvas.drawPath(mPath!!, mPaint!!)
    }



    /**
     * @param startPoint         与中圆圆心重合的那个顶点
     * @param toEdgeMiddleLength startPoint 到对边中点的距离
     * @param edgeLength         startPoint 对边长度的一半
     */
    private fun maketriangel(canvas: Canvas, startPoint: PointF, fishAngle: Float,
                             find_triangle:Float,big_circle_radius:Float) {
      val  triAngle= (fishAngle+Math.cos(Math.toRadians(animatorValue.toDouble()*frequence))*35).toFloat()
        val centerPoint = calculatePoint(startPoint,find_triangle ,triAngle-180)

        val leftPoint = calculatePoint(centerPoint,big_circle_radius ,triAngle+90)
        val rightPoint = calculatePoint(centerPoint,big_circle_radius ,triAngle-90)

        mPath?.reset()
        mPath?.moveTo(startPoint.x,startPoint.y)
        mPath?.lineTo(leftPoint.x,leftPoint.y)
        mPath?.lineTo(rightPoint.x,rightPoint.y)
        canvas.drawPath(mPath!!,mPaint!!)
    }

    //画节支
    private fun makeSegment(
        canvas: Canvas,
        bottomCenterPoint: PointF,
        big_radius: Float,
        small_radius: Float,
        find_middle_circle_length: Float,
        fishAngle: Float,
        hasBig:Boolean

    ):PointF {
        var segmentAngle :Float=0f
        if(hasBig){
            segmentAngle= (fishAngle+Math.cos(Math.toRadians(animatorValue.toDouble()*frequence))*15).toFloat()

        }else{
            segmentAngle= (fishAngle+Math.cos(Math.toRadians(animatorValue.toDouble()*frequence))*35).toFloat()

        }

        //梯形的圆心
        val upCenterPoint = calculatePoint(bottomCenterPoint,find_middle_circle_length,segmentAngle-180)
        //梯形的四个点
        val bottomLeft =calculatePoint(bottomCenterPoint,big_radius,segmentAngle+90)
        val bottomRight =calculatePoint(bottomCenterPoint,big_radius,segmentAngle-90)
        val upLeft =calculatePoint(upCenterPoint,small_radius,segmentAngle+90)
        val upRight =calculatePoint(upCenterPoint,small_radius,segmentAngle-90)
        //画大圆
        if(hasBig){
            canvas.drawCircle(bottomCenterPoint.x,bottomCenterPoint.y,big_radius,mPaint!!)
        }
        //画小圆
        canvas.drawCircle(upCenterPoint.x,upCenterPoint.y,small_radius ,mPaint!!)
        mPath?.reset()
        mPath?.moveTo(upLeft.x,upLeft.y)
        mPath?.lineTo(upRight.x,upRight.y)
        mPath?.lineTo(bottomRight.x,bottomRight.y)
        mPath?.lineTo(bottomLeft.x,bottomLeft.y)
        canvas?.drawPath(mPath!!,mPaint!!)
        return upCenterPoint;
    }
    //yuqi
    private fun makeFins(canvas: Canvas, startPoint: PointF, fishAngle: Float,isRight:Boolean) {
        System.out.println("makeFins======")
        val controlAngle = 115
        //鱼鳍的终点 也是鱼鳍贝塞尔曲线的重点
        val endPoint =calculatePoint(startPoint,FINS_LENTH,fishAngle-180)
        //贝塞尔曲线的控制点
        val controlPoint =
            if(isRight){
                calculatePoint(startPoint,FINS_LENTH*1.8f,fishAngle-controlAngle)
            }else{
                calculatePoint(startPoint,FINS_LENTH*1.8f,fishAngle+controlAngle)
            }

        System.out.println("startPoint======${startPoint.x}---${startPoint.y}")
        mPath?.reset()
      //  移动到起始点
        mPath?.moveTo(startPoint.x,startPoint.y)
       // 贝塞尔曲线
        System.out.println("controlPoint======${controlPoint.x}---${controlPoint.y}")
        System.out.println("endPoint======${endPoint.x}---${endPoint.y}")
        mPath?.quadTo(controlPoint.x,controlPoint.y ,endPoint.x,endPoint.y)
        canvas.drawPath(mPath!!,mPaint!!)
    }

    /**
     * @param startPointF起始点
     * @param length 鱼头摇晃旋转线的长度
     * @param angle 鱼头摇晃的角度
     *
     */
    fun calculatePoint(startPointF: PointF, length: Float, angle: Float): PointF {

        //toRadians角度转弧度
        //鱼头相对远点的x y坐标
        val deltaX: Float = (Math.cos(Math.toRadians(angle.toDouble())) * length).toFloat()
        val deltaY: Float = (Math.sin(Math.toRadians(angle.minus(180).toDouble())) * length).toFloat()
        return PointF(startPointF.x+deltaX,startPointF.y+deltaY)
    }

    //赋值给paint
    override fun setAlpha(alpha: Int) {
        mPaint?.alpha = alpha
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
        mPaint?.colorFilter = colorFilter
    }

    /**
     * 根据透明值调整
     */
    override fun getOpacity(): Int {
        return PixelFormat.TRANSLUCENT
    }

    override fun getIntrinsicHeight(): Int {
        return (9.38 * HEAD_RADIUS).toInt()
    }

    override fun getIntrinsicWidth(): Int {
        return (9.38 * HEAD_RADIUS).toInt()
    }
}